#include "gtest/gtest.h"
#include "mdict.h"
using mdict::MachineDict;

class TestMachineDict : public testing::Test {
protected:
    MachineDict query_dict;
};

// 测试获取definition
TEST_F(TestMachineDict, TestDefinition) {
    // 测试swear
    auto result_vec = query_dict.get_definition_by_word("swear");
    EXPECT_EQ(result_vec.size(), 0);
    // 测试swipe
    result_vec = query_dict.get_definition_by_word("swipe");
    ASSERT_EQ(result_vec.size(), 2);
    EXPECT_EQ(result_vec[0], string("n. a sweeping stroke or blow"));
    EXPECT_EQ(result_vec[1], string("v. strike with a swiping motion"));
}

TEST_F(TestMachineDict, TestTranslation) {
    // 测试swear
    auto result_vec = query_dict.get_translation_by_word("swear");
    ASSERT_EQ(result_vec.size(), 3);
    EXPECT_EQ(result_vec[0], string("vt. 发誓；咒骂"));
    EXPECT_EQ(result_vec[1], string("vi. 发誓，宣誓；诅咒"));
    EXPECT_EQ(result_vec[2], string("n. 宣誓；诅咒"));
    // 测试swipe
    result_vec = query_dict.get_translation_by_word("swipe");
    ASSERT_EQ(result_vec.size(), 2);
    EXPECT_EQ(result_vec[0], string("n. 强打, 用力挥击, 尖刻的话, 碰擦, 起重杆"));
    EXPECT_EQ(result_vec[1], string("vt. 强打, 用力挥击, 偷"));
}

TEST_F(TestMachineDict, TestPronunciation) {
    // 测试swear
    auto result = query_dict.get_pronunciation_by_word("swear");
    EXPECT_EQ(result, string("sweə"));
    // 测试swipe
    result = query_dict.get_pronunciation_by_word("swipe");
    EXPECT_EQ(result, string("swaip"));
}

TEST_F(TestMachineDict, TestExamples) {
    // 测试swear
    auto result_vec = query_dict.get_examples_by_word("swear");
    ASSERT_EQ(result_vec.size(), 8);
    EXPECT_EQ(result_vec[0], string("[with clause]: Maria made me swear I would never tell anyone."));
    EXPECT_EQ(result_vec[1], string("I swear by all I hold dear that I had nothing to do with it."));
    EXPECT_EQ(result_vec[2], string("[with direct speech]: ‘Never again,’ she swore, ‘will I be short of money’."));
    EXPECT_EQ(result_vec[3], string("[with object]: They were reluctant to swear allegiance Law."));
    EXPECT_EQ(result_vec[4], string("[with object] He forced them to swear an oath of loyalty to him."));
    EXPECT_EQ(result_vec[5], string("[with object]: I asked him if he would swear a statement to this effect."));
    EXPECT_EQ(result_vec[6], string("[with object]: I’ve been sworn to secrecy."));
    EXPECT_EQ(result_vec[7], string("[no object]: Peter swore under his breath."));
    // 测试swipe
    result_vec = query_dict.get_examples_by_word("swipe");
    ASSERT_EQ(result_vec.size(), 9);
    EXPECT_EQ(result_vec[0], string("[with object]: She swiped me right across the nose."));
    EXPECT_EQ(result_vec[1], string("[no object]: Lola stood on the balcony, swiping at the moths."));
    EXPECT_EQ(result_vec[2], string("Someone swiped one of his sausages."));
    EXPECT_EQ(result_vec[3], string("'Besides,' he continued, swiping his I.D. pass through an electronic lock, 'the kids trust us.'"));
    EXPECT_EQ(result_vec[4], string("Simply swipe a finger across the phone’s display screen to switch to another program."));
    EXPECT_EQ(result_vec[5], string("[no object]: Swipe to the left on the main navigation page and you’ll see a user login menu."));
    EXPECT_EQ(result_vec[6], string("He missed the ball with his first swipe."));
    EXPECT_EQ(result_vec[7], string("He took a swipe at his critics."));
    EXPECT_EQ(result_vec[8], string("A swipe to the right archives or deletes the message."));
}

TEST_F(TestMachineDict, TestCollinsstar) {
    // 测试swear
    EXPECT_EQ(query_dict.get_collinsstar_by_word("swear"), NO_STAR);
    // 测试swipe
    EXPECT_EQ(query_dict.get_collinsstar_by_word("swipe"), 1);
}

TEST_F(TestMachineDict, TestChanges) {
    // 测试swear
    auto result_vec = query_dict.get_changes_by_word("swear");
    EXPECT_EQ(result_vec.size(), 0);
    // 测试swipe
    result_vec = query_dict.get_changes_by_word("swipe");
    ASSERT_EQ(result_vec.size(), 5);
    EXPECT_EQ(result_vec[0], string("p:swiped"));
    EXPECT_EQ(result_vec[1], string("s:swipes"));
    EXPECT_EQ(result_vec[2], string("3:swipes"));
    EXPECT_EQ(result_vec[3], string("d:swiped"));
    EXPECT_EQ(result_vec[4], string("i:swiping"));
}

TEST_F(TestMachineDict, TestAllinfo) {
    // 因为特殊机制的原因(上面测试的接口实际上是这个的一个局部值引用返回)，这个测试用例仅仅检测是否正常返回，简单检测一下内容
    // 测试swear
    auto result = query_dict.get_allinfo_by_word("swear");
    EXPECT_EQ(result.word, string("swear"));
    EXPECT_EQ(result.definition.size(), 0);
    EXPECT_EQ(result.translation.size(), 3);
    EXPECT_EQ(result.examples.size(), 8);
    EXPECT_EQ(result.pronunciation, string("sweə"));
    EXPECT_EQ(result.collins_star, NO_STAR);
    EXPECT_EQ(result.changes.size(), 0);
    // 测试swipe
    result = query_dict.get_allinfo_by_word("swipe");
    EXPECT_EQ(result.word, string("swipe"));
    EXPECT_EQ(result.definition.size(), 2);
    EXPECT_EQ(result.translation.size(), 2);
    EXPECT_EQ(result.examples.size(), 9);
    EXPECT_EQ(result.pronunciation, string("swaip"));
    EXPECT_EQ(result.collins_star, 1);
    EXPECT_EQ(result.changes.size(), 5);
}

TEST_F(TestMachineDict, TestRangeResult) {
    // 假设单个单词的测试已经没有问题
    auto result_vec = query_dict.get_result_by_range(309, 314);
    ASSERT_EQ(result_vec.size(), 6);
    EXPECT_EQ(result_vec[0].word, string("do"));
    EXPECT_EQ(result_vec[1].word, string("dobe"));
    EXPECT_EQ(result_vec[2].word, string("dog"));
    EXPECT_EQ(result_vec[3].word, string("dogs"));
    EXPECT_EQ(result_vec[4].word, string("droid"));
    EXPECT_EQ(result_vec[5].word, string("droids"));
}

TEST_F(TestMachineDict, TestResultReturn) {
    // 先进行range查询，然后返回结果
    query_dict.get_result_by_range(309, 314);
    auto result_vec = query_dict.get_result_vector();
    ASSERT_EQ(result_vec.size(), 6);
    EXPECT_EQ(result_vec[0].word, string("do"));
    EXPECT_EQ(result_vec[1].word, string("dobe"));
    EXPECT_EQ(result_vec[2].word, string("dog"));
    EXPECT_EQ(result_vec[3].word, string("dogs"));
    EXPECT_EQ(result_vec[4].word, string("droid"));
    EXPECT_EQ(result_vec[5].word, string("droids"));
    query_dict.get_allinfo_by_word("swear");
    result_vec = query_dict.get_result_vector();
    ASSERT_EQ(result_vec.size(), 2); // 这里数据库出了点问题，数据库存了两条这样的数据
    auto result = result_vec[0];
    EXPECT_EQ(result.word, string("swear"));
    EXPECT_EQ(result.definition.size(), 0);
    EXPECT_EQ(result.translation.size(), 3);
    EXPECT_EQ(result.examples.size(), 8);
    EXPECT_EQ(result.pronunciation, string("sweə"));
    EXPECT_EQ(result.collins_star, NO_STAR);
    EXPECT_EQ(result.changes.size(), 0);
}

TEST_F(TestMachineDict, TestNull) {
    auto result_vec = query_dict.get_definition_by_word("");
    EXPECT_EQ(result_vec.size(), 0);
    result_vec = query_dict.get_translation_by_word("");
    EXPECT_EQ(result_vec.size(), 0);
    result_vec = query_dict.get_examples_by_word("");
    EXPECT_EQ(result_vec.size(), 0);
    result_vec = query_dict.get_changes_by_word("");
    EXPECT_EQ(result_vec.size(), 0);
    auto allinfo = query_dict.get_allinfo_by_word("");
    EXPECT_EQ(allinfo.word, string(""));
    auto result_string = query_dict.get_pronunciation_by_word("");
    EXPECT_EQ(result_string, string(""));
    auto result_integer = query_dict.get_collinsstar_by_word("");
    EXPECT_EQ(result_integer, NO_STAR);
}

TEST_F(TestMachineDict, TestInitialize) {
    auto result_vec = query_dict.get_result_vector();
    EXPECT_EQ(result_vec.size(), 1);
}

TEST_F(TestMachineDict, TestRangeFault) {
    auto result_vec = query_dict.get_result_by_range(45, 32); // 测试反界
    EXPECT_EQ(result_vec.size(), 0);
    result_vec = query_dict.get_result_by_range(0, 5); //测试零界
    EXPECT_EQ(result_vec.size(), 0);
    result_vec = query_dict.get_result_by_range(3402560, 3402565); // 右边的数字刚刚好越界
    EXPECT_EQ(result_vec.size(), 0);
    // 应该设置一个最大范围防止内存放不下
    result_vec = query_dict.get_result_by_range(100, 100000);
    EXPECT_LE(result_vec.size(), MAX_RECORDS);
}

// 如果链接到gtest_main库，不需要写主函数
int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS(); // 该函数的返回值不能够忽略，主函数必须返回它
}